#include "DeskTidyWnd.h"

///Copyright (c) 2009-2010 T. Klepzig 

int DeskTidyWnd::Height=32;


DeskTidyWnd::DeskTidyWnd(DTWNDEVENTPROC ptr, int id, bool removable)
{
	currentPage = 1;
	roundCorner=12;
	active=false;
	locked=false;
	this->id = id;
	this->removable=removable;
	onActiveChangedPtr = ptr;
	
	onSwitchToNextPagePtr = 0;
	onSwitchToPrevPagePtr = 0;
	onRefreshPtr = 0;
	onLockChangedPtr = 0;
	onNewClickedPtr = 0;
	onRemoveClickedPtr = 0;
	onPropertiesClickedPtr = 0;

	buttonNextPage = 0;
	buttonPrevPage = 0;
}

DeskTidyWnd::~DeskTidyWnd()
{
	DestroyMenu(systemMenu);
}


void DeskTidyWnd::Create(HINSTANCE hInstance, LPCTSTR text, RECT bounds)
{
	BOOL dwmEnabled;
	DwmIsCompositionEnabled(&dwmEnabled);	

	CustomWindow::Create(hInstance, TEXT("DeskTidyWindow"), WndProc, WS_EX_TOOLWINDOW, !dwmEnabled ? WS_POPUP | WS_THICKFRAME : WS_THICKFRAME, CS_NOCLOSE | CS_HREDRAW, !dwmEnabled ? GetSysColorBrush(COLOR_GRADIENTACTIVECAPTION) : GetStockBrush(BLACK_BRUSH), 0, LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1)));
	this->SetText(text);
	this->SetScreenDockingRange(DeskTidyWnd::Height / 2);
	this->SetLocation(bounds.left, bounds.top);
	this->SetSize(RECTWIDTH(bounds), Height);

	RECT clientRect;
	GetClientRect(this->GetHWnd(), &clientRect);

	buttonPrevPage = new PaintedButton(this->GetHWnd());
	buttonPrevPage->Clicked(buttonPrevPage_Clicked);
	
	if (dwmEnabled)
	{
		buttonPrevPage->SetLocation(5, 5);
		buttonPrevPage->SetSize(22, 22);
	}
	else
	{
		buttonPrevPage->SetLocation(0, 0);
		buttonPrevPage->SetSize(18, 18);
	}

	
	buttonNextPage = new PaintedButton(this->GetHWnd());
	buttonNextPage->Clicked(buttonNextPage_Clicked);
	
	if (dwmEnabled)
	{
		buttonNextPage->SetLocation(this->GetSize().cx - 27, this->GetSize().cy - 27);
		buttonNextPage->SetSize(22, 22);
	}
	else
	{
		buttonNextPage->SetLocation(RECTWIDTH(clientRect) - 18, RECTHEIGHT(clientRect) - 18);
		buttonNextPage->SetSize(18, 18);
	}
	

	ChangeWindowMessageFilterEx(this->GetHWnd(), WM_DWMCOLORIZATIONCOLORCHANGED, MSGFLT_ALLOW, 0);

	if (!dwmEnabled)
	{
		roundCorner = 0;
	}
	else
	{
		roundCorner = 12;

		MARGINS margins = {-1,-1,-1,-1};
		DwmExtendFrameIntoClientArea(this->GetHWnd(),&margins);
	}

	this->SetFrameMargins(8, 8, 0, 0);

	systemMenu = CreatePopupMenu();
	InsertMenu(systemMenu,0,MF_STRING|MF_BYPOSITION, MENUOPEN, Translate(TEXT("Open")).c_str());
	InsertMenu(systemMenu,1,MF_STRING|MF_BYPOSITION, MENULOCK, Translate(TEXT("Lock")).c_str());
	InsertMenu(systemMenu,2,MF_SEPARATOR|MF_BYPOSITION, 0, 0);
	InsertMenu(systemMenu,3,MF_STRING|MF_BYPOSITION, MENUNEW, Translate(TEXT("New")).c_str());
	InsertMenu(systemMenu,4,MF_STRING|MF_BYPOSITION, MENUREMOVE, Translate(TEXT("Remove")).c_str());
	
	if (!removable)
		EnableMenuItem(systemMenu, MENUREMOVE, MF_DISABLED);
	
	InsertMenu(systemMenu,5,MF_SEPARATOR|MF_BYPOSITION, 1, 0);
	InsertMenu(systemMenu,6,MF_STRING|MF_BYPOSITION, MENUPROPERTIES, Translate(TEXT("Properties")).c_str());
	InsertMenu(systemMenu,7,MF_SEPARATOR|MF_BYPOSITION, 2, 0);
	InsertMenu(systemMenu,8,MF_STRING|MF_BYPOSITION, MENUREFRESH, Translate(TEXT("Refresh")).c_str());

	SetMenuDefaultItem(systemMenu,MENUOPEN,false);

	BOOL bl=TRUE;
	DwmSetWindowAttribute(this->GetHWnd(),DWMWA_DISALLOW_PEEK,&bl, sizeof(bl));
	DwmSetWindowAttribute(this->GetHWnd(),DWMWA_EXCLUDED_FROM_PEEK,&bl, sizeof(bl));

	DWMFLIP3DWINDOWPOLICY flip3DPolicy = DWMFLIP3D_EXCLUDEBELOW;
	DwmSetWindowAttribute(this->GetHWnd(), DWMWA_FLIP3D_POLICY, &flip3DPolicy, sizeof(DWMWA_FLIP3D_POLICY));
		
	Utilities::MoveWindowIntoVisibleArea(this->GetHWnd());
}

void DeskTidyWnd::SetDwmCompatibleWindowProperties(BOOL dwmEnabled)
{
	if (!dwmEnabled)
	{			
		SetClassLongPtr(this->GetHWnd(), GCL_HBRBACKGROUND, (LONG)GetSysColorBrush(COLOR_GRADIENTACTIVECAPTION));
		SetWindowLongPtr(this->GetHWnd(), GWL_STYLE, GetWindowLongPtr(this->GetHWnd(), GWL_STYLE) | WS_POPUP);
		SetWindowLongPtr(this->GetHWnd(), GWL_STYLE, GetWindowLongPtr(this->GetHWnd(), GWL_STYLE) & ~WS_CAPTION);
		roundCorner = 0;

		RECT clientRect;
		GetClientRect(this->GetHWnd(), &clientRect);

		buttonPrevPage->SetLocation(0, 0);
		buttonPrevPage->SetSize(18, 18);
		buttonNextPage->SetLocation(RECTWIDTH(clientRect) - 18, RECTHEIGHT(clientRect) - 18);
		buttonNextPage->SetSize(18, 18);
	}
	else
	{
		SetClassLongPtr(this->GetHWnd(), GCL_HBRBACKGROUND, (LONG)GetStockObject(BLACK_BRUSH));
		SetWindowLongPtr(this->GetHWnd(), GWL_STYLE, GetWindowLongPtr(this->GetHWnd(), GWL_STYLE) & ~WS_POPUP);
		SetWindowLongPtr(this->GetHWnd(), GWL_STYLE, GetWindowLongPtr(this->GetHWnd(), GWL_STYLE) | WS_CAPTION);
		roundCorner = 12;
		buttonPrevPage->SetLocation(5, 5);
		buttonPrevPage->SetSize(22, 22);
		buttonNextPage->SetLocation(this->GetSize().cx - 27, this->GetSize().cy - 27);
		buttonNextPage->SetSize(22, 22);

		MARGINS margins = {-1,-1,-1,-1};
		DwmExtendFrameIntoClientArea(this->GetHWnd(),&margins);
	}
	InvalidateRgn(this->GetHWnd(),0,true);
}

void DeskTidyWnd::SetBounds(RECT value)
{
	CustomWindow::SetBounds(value.left, value.top, value.right, value.top + DeskTidyWnd::Height);
}

void DeskTidyWnd::SetBounds(LONG left, LONG top, LONG right, LONG bottom)
{
	CustomWindow::SetBounds(left, top, right, top + DeskTidyWnd::Height);
}

void DeskTidyWnd::SetSize(SIZE value)
{
	CustomWindow::SetSize(value.cx, DeskTidyWnd::Height);
}

void DeskTidyWnd::SetSize(LONG cx, LONG cy)
{
	CustomWindow::SetSize(cx, DeskTidyWnd::Height);
}

bool DeskTidyWnd::GetLocked()
{
	return locked;
}

void DeskTidyWnd::SetLocked(bool value)
{
	locked=value;
	CheckMenuItem(systemMenu, MENULOCK, value ? MF_CHECKED : MF_UNCHECKED);
}

bool DeskTidyWnd::GetActive()
{
	return active;
}

void DeskTidyWnd::SetActive(bool value)
{
	active = value;

	ModifyMenu(systemMenu,MENUOPEN,MF_STRING|MF_BYCOMMAND,MENUOPEN,active ? Translate(TEXT("Close")).c_str() : Translate(TEXT("Open")).c_str());
	EnableMenuItem(systemMenu, MENULOCK, active ? MF_DISABLED : MF_ENABLED);
}

int DeskTidyWnd::GetId()
{
	return id;
}

void DeskTidyWnd::SetCurrentPage(int page)
{
	this->currentPage = page;
}

int DeskTidyWnd::GetCurrentPage()
{
	return currentPage;
}

void DeskTidyWnd::ShowPageButtons(bool prevPage, bool nextPage)
{
	if (prevPage)
		buttonPrevPage->Show();
	else
		buttonPrevPage->Hide();

	if (nextPage)
		buttonNextPage->Show();
	else
		buttonNextPage->Hide();

	this->Refresh();
}


void DeskTidyWnd::SetManipulateOptionsDisabled(bool value)
{
	if (removable)
		EnableMenuItem(systemMenu, MENUREMOVE, value ? MF_ENABLED : MF_DISABLED);

	EnableMenuItem(systemMenu, MENUPROPERTIES, value ? MF_ENABLED : MF_DISABLED);	
}


void DeskTidyWnd::SetSwitchToNextPagePtr(DTWNDEVENTPROC ptr)
{
	onSwitchToNextPagePtr = ptr;
}

void DeskTidyWnd::SetSwitchToPrevPagePtr(DTWNDEVENTPROC ptr)
{
	onSwitchToPrevPagePtr = ptr;
}

void DeskTidyWnd::SetOnRefreshPtr(DTWNDEVENTPROC ptr)
{
	onRefreshPtr = ptr;
}

void DeskTidyWnd::SetOnLockChangedPtr(DTWNDEVENTPROC ptr)
{
	onLockChangedPtr = ptr;
}

void DeskTidyWnd::SetOnNewClickedPtr(DTWNDEVENTPROC ptr)
{
	onNewClickedPtr = ptr;
}

void DeskTidyWnd::SetOnRemoveClickedPtr(DTWNDEVENTPROC ptr)
{
	onRemoveClickedPtr = ptr;
}

void DeskTidyWnd::SetOnPropertiesClickedPtr(DTWNDEVENTPROC ptr)
{
	onPropertiesClickedPtr = ptr;
}



HWND DeskTidyWnd::GetLastWindowExcludingDTWnd()
{	
	HWND last = GetWindow(Utilities::GetDesktopWindow(Utilities::DW_SHELLDLL_DefViewParent), GW_HWNDPREV);
	
	TCHAR className[255] = {0};
	GetClassName(last, className, sizeof(className));

	while ((!IsWindow(last)
		|| !IsWindowVisible(last)
		|| IsIconic(last)
		|| Utilities::IsSpecialWindow(last)
		|| !_tcscmp(className, TEXT("DeskTidyWindow")))
		&& last)
	{
		last=GetWindow(last, GW_HWNDPREV);
		GetClassName(last, className, sizeof(className));
	}

	return last;
}

void DeskTidyWnd::CallDTWndEvent(DTWNDEVENTPROC ptr, DeskTidyWnd* sender)
{
	if (ptr)
		ptr(sender);
}

void DeskTidyWnd::ToggleActiveState(HWND hWnd)
{
	((DeskTidyWnd*)instances[hWnd])->SetActive(!((DeskTidyWnd*)instances[hWnd])->GetActive());
	CallDTWndEvent(((DeskTidyWnd*)instances[hWnd])->onActiveChangedPtr, ((DeskTidyWnd*)instances[hWnd]));	
}

RECT DeskTidyWnd::DockDTWnd(HWND hWnd, HWND movedHWnd)
{	
	RECT bounds={0};
	GetWindowRect(movedHWnd, &bounds);

	TCHAR className1[255] = {0};
	TCHAR className2[255] = {0};
	GetClassName(hWnd, className1, sizeof(className1));
	GetClassName(hWnd, className2, sizeof(className2));

	if (hWnd == movedHWnd
		|| (hWnd && !IsWindowVisible(hWnd))
		|| _tcscmp(className1, TEXT("DeskTidyWindow"))
		|| _tcscmp(className2, TEXT("DeskTidyWindow")))
		return bounds;	

	int x = bounds.left;
	int y = bounds.top;
	int width = RECTWIDTH(bounds);
	int height = RECTHEIGHT(bounds);

	RECT rect={0};
	GetWindowRect(hWnd, &rect);

	if ((bounds.right > rect.left) && (bounds.left < rect.right))
	{
		if (bounds.top >= (rect.bottom-DeskTidyWnd::Height) && bounds.top <= (rect.bottom+25))
			y = rect.bottom;

		else if (bounds.bottom >= (rect.top-25) && bounds.bottom <= (rect.top+DeskTidyWnd::Height))
			y = rect.top-RECTHEIGHT(bounds);
	}

	bounds.left = x;
	bounds.top = y;
	bounds.right = x + width;
	bounds.bottom = y + height;

	if ((bounds.bottom >= rect.top) && (bounds.top <= rect.bottom))
	{
		if (bounds.right > (rect.left-25) && bounds.right < rect.left)
		{
			x = rect.left-RECTWIDTH(bounds);
			y = rect.top;
		}
		else if(bounds.left < (rect.right+25) && bounds.left > rect.right)
		{
			x = rect.right;
			y = rect.top;
		}

		bounds.left = x;
		bounds.top = y;
		bounds.right = x + width;
		bounds.bottom = y + height;

		if (bounds.left >= (rect.left-25) && bounds.left <= (rect.left+25))
		{
			if (bounds.right == rect.right)
			{
				x = rect.left;
				width = RECTWIDTH(rect);
			}
			else
				x = rect.left;
		}

		bounds.left = x;
		bounds.top = y;
		bounds.right = x + width;
		bounds.bottom = y + height;

		if (bounds.right >= (rect.right-25) && bounds.right <= (rect.right+25))
		{
			if (bounds.left == rect.left)
			{
				x = rect.left;
				width = RECTWIDTH(rect);
			}
			else
				x = rect.right-RECTWIDTH(bounds);
		}
	}

	bounds.left = x;
	bounds.top = y;
	bounds.right = x + width;
	bounds.bottom = y + height;

	return bounds;
}


void DeskTidyWnd::buttonPrevPage_Clicked(PaintedButton* sender, LPVOID tag)
{
	DeskTidyWnd* instance = (DeskTidyWnd*)instances[sender->GetParentWindow()];

	if (instance->onSwitchToPrevPagePtr)
		instance->onSwitchToPrevPagePtr(instance);
}

void DeskTidyWnd::buttonNextPage_Clicked(PaintedButton* sender, LPVOID tag)
{
	DeskTidyWnd* instance = (DeskTidyWnd*)instances[sender->GetParentWindow()];
	
	if (instance->onSwitchToNextPagePtr)
		instance->onSwitchToNextPagePtr(instance);
}

LRESULT CALLBACK DeskTidyWnd::WndProc(LPVOID sender, HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{	
	static bool windowMoved = false;
	static Color dwmColor = 0;

	DeskTidyWnd* instance = (DeskTidyWnd*)instances[hWnd];

	if (!dwmColor.GetValue())
	{
		DWORD cr;
		BOOL opaqueBlend;
		DwmGetColorizationColor(&cr, &opaqueBlend);
		cr = 0x3C000000 | (cr & 0x00FFFFFF);
		dwmColor.SetValue(cr);
	}

	static BOOL dwmEnabled = -1;
	
	if (dwmEnabled == -1)
		DwmIsCompositionEnabled(&dwmEnabled);

	if (instance->buttonNextPage && instance->buttonNextPage->HandleWndProc(hWnd, uMsg, wParam, lParam))
		return DefWindowProc(hWnd, uMsg, wParam, lParam);

	if (instance->buttonPrevPage && instance->buttonPrevPage->HandleWndProc(hWnd, uMsg, wParam, lParam))
		return DefWindowProc(hWnd, uMsg, wParam, lParam);

	switch (uMsg)
	{
	case WM_WINDOWPOSCHANGING:
		{
			//always at bottom
			WINDOWPOS* wp = (WINDOWPOS*)lParam;
			wp->hwndInsertAfter = GetLastWindowExcludingDTWnd();

			//Alternative to DockDTWnd at EXITMOVESIZE: Dock during moving
			//but it needs too much poerformance...
			//and user handling is also not so great...
			{
				/*map<HWND, Window*>::iterator iter;
				for (iter = instances.begin(); iter != instances.end(); iter++)
				{
					if (iter->second->GetHWnd() != hWnd)
					{
						RECT secondRect = iter->second->GetBounds();

						if ((PWPRIGHT(wp) > secondRect.left) && (wp->x < secondRect.right))
						{
							if (wp->y >= (secondRect.bottom - DeskTidyWnd::Height) && wp->y <= (secondRect.bottom + 25))
								wp->y = secondRect.bottom;

							else if (PWPBOTTOM(wp) >= (secondRect.top - 25) && PWPBOTTOM(wp) <= (secondRect.top + DeskTidyWnd::Height))
								wp->y = secondRect.top - wp->cy;
						}


						if ((PWPBOTTOM(wp) >= secondRect.top) && (wp->y <= secondRect.bottom))
						{
							if (PWPRIGHT(wp) > (secondRect.left - 25) && PWPRIGHT(wp) < secondRect.left)
							{
								wp->x = secondRect.left - wp->cx;
								wp->y = secondRect.top;
							}
							else if(wp->x < (secondRect.right + 25) && wp->x > secondRect.right)
							{
								wp->x = secondRect.right;
								wp->y = secondRect.top;
							}

							if (wp->x >= (secondRect.left - 25) && wp->x <= (secondRect.left + 25))
							{
								if (PWPRIGHT(wp) == secondRect.right)
								{
									wp->x = secondRect.left;
									wp->cx = RECTWIDTH(secondRect);
								}
								else
									wp->x = secondRect.left;
							}

							if (PWPRIGHT(wp) >= (secondRect.right - 25) && PWPRIGHT(wp) <= (secondRect.right + 25))
							{
								if (wp->x == secondRect.left)
								{
									wp->x = secondRect.left;
									wp->cx = RECTWIDTH(secondRect);
								}
								else
									wp->x = secondRect.right - wp->cx;
							}
						}
					}
				}*/
			}

			lParam = (LPARAM)wp;

			return S_OK;
		}
	case WM_COMMAND:
		{
			switch (LOWORD(wParam))
			{
			case MENUOPEN:
				{
					ToggleActiveState(hWnd);
					break;
				}
			case MENULOCK:
				{
					if (instance->locked = !instance->locked)
						CheckMenuItem(instance->systemMenu,MENULOCK,MF_CHECKED);
					else
						CheckMenuItem(instance->systemMenu,MENULOCK,MF_UNCHECKED);

					CallDTWndEvent(instance->onLockChangedPtr, instance);

					break;
				}
			case MENUNEW:
				{
					CallDTWndEvent(instance->onNewClickedPtr, instance);
					break;
				}
			case MENUREMOVE:
				{
					CallDTWndEvent(instance->onRemoveClickedPtr, instance);
					break;
				}
			case MENUPROPERTIES:
				{
					CallDTWndEvent(instance->onPropertiesClickedPtr, instance);
					break;
				}
			case MENUREFRESH:
				{
					CallDTWndEvent(instance->onRefreshPtr, instance);
					break;
				}
			}
			break;
		}
	case WM_RBUTTONDOWN:
	case WM_CONTEXTMENU:
		{
			POINT cursorPos=Utilities::GetCursorPosition();
			SetForegroundWindow(hWnd);
			TrackPopupMenu(instance->systemMenu,TPM_VERNEGANIMATION | TPM_LEFTBUTTON,cursorPos.x,cursorPos.y,0,hWnd,0);
			PostMessage(hWnd, WM_NULL, 0, 0);
			break;
		}
	case WM_SETCURSOR:
		{		
			if (LOWORD(lParam) == HTTOP || LOWORD(lParam) == HTBOTTOM)
				lParam = MAKELPARAM(HTNOWHERE, HIWORD(lParam));

			else if (LOWORD(lParam) == HTTOPLEFT || LOWORD(lParam) == HTBOTTOMLEFT)
				lParam = MAKELPARAM(HTLEFT, HIWORD(lParam));
			
			else if (LOWORD(lParam) == HTTOPRIGHT || LOWORD(lParam) == HTBOTTOMRIGHT)
				lParam = MAKELPARAM(HTRIGHT, HIWORD(lParam));

			break;
		}
	case WM_DWMCOLORIZATIONCOLORCHANGED:
		{
			DWORD cr;
			BOOL opaqueBlend;
			DwmGetColorizationColor(&cr, &opaqueBlend);
			cr = 0x3C000000 | (cr & 0x00FFFFFF);
			dwmColor.SetValue(cr);

			InvalidateRgn(hWnd, 0, TRUE);

			break;
		}
	case WM_PAINT:
		{	
			HDC          hdc;
			PAINTSTRUCT  ps;

			hdc = BeginPaint(hWnd, &ps);

			RECT clientRect;
			GetClientRect(hWnd,&clientRect);	
			
			Utilities::DrawDwmCompatibleText(clientRect, hdc, instance->GetText().c_str(), 12, RGB(0, 0, 0), DT_CENTER | DT_END_ELLIPSIS | DT_VCENTER | DT_SINGLELINE, FW_NORMAL, 10, 0, 0);
			

			SolidBrush brush(dwmColor);
			GraphicsPath fillPath;

			Graphics graphics(hdc);
			graphics.SetSmoothingMode(SmoothingModeAntiAlias);

			Utilities::CreateRoundRectPath(&fillPath, clientRect, instance->roundCorner);
			graphics.FillPath(&brush,&fillPath);

			if (dwmEnabled)
			{
				if (instance->buttonPrevPage->IsVisible())
					Utilities::DrawPNGFromResource(instance->hInstance, hdc, MAKEINTRESOURCE(IDB_ArrowLeft), 10, 11, 10, 10);

				if (instance->buttonNextPage->IsVisible())
					Utilities::DrawPNGFromResource(instance->hInstance, hdc, MAKEINTRESOURCE(IDB_ArrowRight), instance->GetSize().cx - 21,  instance->GetSize().cy - 21, 10, 10);
			}
			else
			{
				if (instance->buttonPrevPage->IsVisible())
					Utilities::DrawPNGFromResource(instance->hInstance, hdc, MAKEINTRESOURCE(IDB_ArrowBlackLeft), 3, 4, 10, 10);

				if (instance->buttonNextPage->IsVisible())
					Utilities::DrawPNGFromResource(instance->hInstance, hdc, MAKEINTRESOURCE(IDB_ArrowBlackRight), RECTWIDTH(clientRect) - 14,  RECTHEIGHT(clientRect) - 14, 10, 10);
			}

			instance->buttonNextPage->HandlePainting(hdc);
			instance->buttonPrevPage->HandlePainting(hdc);

			EndPaint(hWnd, &ps);

			break;			
		}
	case WM_DWMCOMPOSITIONCHANGED:
		{
			DwmIsCompositionEnabled(&dwmEnabled);
			instance->SetDwmCompatibleWindowProperties(dwmEnabled);

			break;
		}
	case WM_LBUTTONDOWN:
		{
			windowMoved = false;

			SendMessage(hWnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, 0);
			SendMessage(hWnd, WM_LBUTTONUP, 0, 0);
		
			break;
		}
	case WM_LBUTTONUP:
		{		
			if (!windowMoved)
				ToggleActiveState(hWnd);

			break;
		}
	case WM_ENTERSIZEMOVE:
		{
			windowMoved = true;
		}
	case WM_EXITSIZEMOVE:
		{
			map<HWND, Window*>::iterator iter;
			for (iter = instances.begin(); iter != instances.end(); iter++)
			{
				if (iter->second->GetHWnd() != hWnd)
					instances[hWnd]->SetBounds(DockDTWnd(iter->second->GetHWnd(), hWnd));
			}

			if (instance && instance->active)
				CallDTWndEvent(instance->onActiveChangedPtr, instance);

			break;
		}
	case WM_NCLBUTTONDOWN:  
		{
			if (wParam != HTTOPLEFT
				&& wParam != HTBOTTOMLEFT
				&& wParam !=  HTTOPRIGHT
				&& wParam !=  HTBOTTOMRIGHT
				&& wParam !=  HTLEFT
				&& wParam !=  HTRIGHT)
			{
				wParam = HTCAPTION;
			}

			break;
		}
	case WM_MOUSEMOVE:  
		{
			//old, prevent PaintedButton Click when the window is inactive
			//if (wParam == MK_LBUTTON)
			//{			
			//	//sems to be needless...
			//	//ReleaseCapture();
			//	SendMessage(hWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0);
			//	//because of the manipulation above this sendmessage is needed
			//	//because a WM_LBUTTONUP Message is not sent right at the
			//	//moment of the activation of the window
			//	SendMessage(hWnd, WM_LBUTTONUP, 0, 0);
			//}

			break;
		}	
	case WM_GETMINMAXINFO:
		{
			MINMAXINFO * mmi = (MINMAXINFO*)lParam;
			mmi->ptMinTrackSize.x = GetSystemMetrics(SM_CXMINTRACK);
			mmi->ptMinTrackSize.y = DeskTidyWnd::Height;
			mmi->ptMaxTrackSize.x = GetSystemMetrics(SM_CXMAXTRACK);
			mmi->ptMaxTrackSize.y = DeskTidyWnd::Height;

			return S_OK;
		}	
	case WM_SIZE:
		{
			if (instance->buttonNextPage)
			{
				RECT clientRect;
				GetClientRect(hWnd,&clientRect);	

				if (dwmEnabled)
					instance->buttonNextPage->SetLocation(instance->GetSize().cx - 27, instance->GetSize().cy - 27);
				else
					instance->buttonNextPage->SetLocation(RECTWIDTH(clientRect) - 18, RECTHEIGHT(clientRect) - 18);
			}
			break;
		}
	}

	return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

